package net.sourceforge.openclixml.ext;

import net.sourceforge.openclixml.ClixmlException;
import net.sourceforge.openclixml.EvaluationFailedException;
import net.sourceforge.openclixml.environment.IEnvironment;

import org.w3c.dom.Document;

import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.xml.xpath.XPathExpressionException;


/**
 *
 * @version $Revision: 50 $
 * @author dominikjungo
 *
 * Last changed: $Date: 2008-04-09 22:33:10 +0200 (Wed, 09 Apr 2008) $
 * The License for this file can be found in doc/Licenses/license-OpenCliXML.txt
 */
public class ForAllType extends net.sourceforge.openclixml.autogen.ForAllType {
    /**
     * Applies the for all operator on all its children.
     *
     * {@inheritDoc}
     *
     */
    @Override
    public boolean evalDelegated(
        final IEnvironment<String, String> environment,
        final Map<String, Document> systemUnderTest)
        throws EvaluationFailedException {
        setSuccess(true);

        FormulaType child = null;

        try {
            child = getChildElement(); //ElementManipulator.getChild(this);

            setChildNull();

            for (int i = 1; i <= getSteps(environment, systemUnderTest); i++) {
                //TODO variable name
                IEnvironment<String, String> e = environment.extend(getLocator()
                                                                        .getVariable(),
                        getLocator().getXpath() + "[" + i + "]");

                FormulaType clone = (FormulaType) child.clone();

                LoopType loopChild = new LoopType();
                loopChild.setXpath(getLocator().getXpath() + "[" + i + "]");
                loopChild.setVariable(getLocator().getVariable());
                loopChild.setChild(clone);
                getLoop().add(loopChild);

                if (!clone.eval(e, systemUnderTest)) {
                    setSuccess(false);

                    if (isOptimise()) {
                        return false;
                    }
                }
            }
        } catch (CloneNotSupportedException ex) {
            Logger.getLogger(ForAllType.class.getName())
                  .log(Level.SEVERE, null, ex);

            //TODO handle this
        } catch (ClixmlException e) {
            throw new EvaluationFailedException("no children found", e); //mhhh? no children
        } catch (XPathExpressionException e) {
            throw new EvaluationFailedException("XPath evaluation failed", e);
        }

        return success;
    }
}
